package com.huangyi.portalservice.user.service.impl;



import com.huangyi.adminapi.appuser.domain.dto.UserEditReqDTO;
import com.huangyi.adminapi.appuser.domain.vo.AppUserVo;
import com.huangyi.adminapi.appuser.feign.AppUserFeignClient;
import com.huangyi.commoncore.utils.VerifyUtil;
import com.huangyi.commondomain.domain.R;
import com.huangyi.commondomain.domain.ResultCode;
import com.huangyi.commondomain.exception.ServiceException;
import com.huangyi.commonmessage.service.MessageService;
import com.huangyi.commonsecurity.dto.LoginUserDTO;
import com.huangyi.commonsecurity.dto.TokenDTO;
import com.huangyi.commonsecurity.service.TokenService;
import com.huangyi.commonsecurity.utils.JwtUtil;
import com.huangyi.commonsecurity.utils.SecurityUtil;
import com.huangyi.portalservice.user.entity.dto.CodeLoginDTO;
import com.huangyi.portalservice.user.entity.dto.LoginDTO;
import com.huangyi.portalservice.user.entity.dto.UserDTO;
import com.huangyi.portalservice.user.entity.dto.WechatLoginDTO;
import com.huangyi.portalservice.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * 门户用户服务实现类
 */
@Component
@Slf4j
@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private AppUserFeignClient appUserFeignClient;

    @Autowired
    private MessageService messageService;

    @Autowired
    private TokenService tokenService;
    /**
     * 登录逻辑
     * @param loginDTO 用户生命周期对象
     * @return token令牌
     */
    @Override
    public TokenDTO login(LoginDTO loginDTO) {
        // 1 设置用户生命周期, 使用 LoginUserDTO 构建 token
        LoginUserDTO loginUserDTO = new LoginUserDTO();
        if(loginDTO==null){
            return null;
        }
        if(loginDTO instanceof WechatLoginDTO wechatLoginDTO){
            // 微信用户登录
            loginByWechat(wechatLoginDTO,loginUserDTO);
        }else if(loginDTO instanceof CodeLoginDTO codeLoginDTO){
            loginByCode(codeLoginDTO,loginUserDTO);
        }
        loginUserDTO.setUserFrom("app");
        return tokenService.createToken(loginUserDTO);
    }

    /**
     * 验证码登录逻辑
     * @param codeLoginDTO 手机号登录DTO
     * @param loginUserDTO 用户信息上下文
     */
    private void loginByCode(CodeLoginDTO codeLoginDTO,LoginUserDTO loginUserDTO) {
        // 1 校验手机号
        if(codeLoginDTO==null){
            throw new ServiceException("用户信息不能为空", ResultCode.INVALID_PARA.getCode());
        }
        if(!VerifyUtil.checkPhone(codeLoginDTO.getPhone())){
            throw new ServiceException("手机号格式错误", ResultCode.INVALID_PARA.getCode());
        }
        // 2 执行远程调用
        R<AppUserVo> appUserVoR = appUserFeignClient.findByPhone(codeLoginDTO.getPhone());
        AppUserVo appUserVo = new AppUserVo();
        //注册逻辑
        if(appUserVoR == null || appUserVoR.getCode() != ResultCode.SUCCESS.getCode() || appUserVoR.getData() == null){
            appUserVo = register(codeLoginDTO);
        }else {
            appUserVo = appUserVoR.getData();
        }
        // 校验验证码
        String cacheCode = messageService.getCode(codeLoginDTO.getPhone());
        if (cacheCode == null) {
            throw new ServiceException("验证码无效", ResultCode.INVALID_PARA.getCode());
        }
        if (!cacheCode.equals(codeLoginDTO.getCode())) {
            throw new ServiceException("验证码错误", ResultCode.INVALID_PARA.getCode());
        }
        // 5 校验验证码通过
        messageService.deleteCode(codeLoginDTO.getPhone());
        // 6 设置登录信息
        loginUserDTO.setUserId(appUserVo.getUserId());
        loginUserDTO.setUserName(appUserVo.getNickName());

    }

    /**
     * 修改用户信息
     * @param userEditReqDTO C端用户编辑DTO
     * @return void
     */
    @Override
    public void edit(UserEditReqDTO userEditReqDTO) {
         R<Void> result = appUserFeignClient.edit(userEditReqDTO);
         if(result == null || result.getCode() != ResultCode.SUCCESS.getCode()){
             throw new ServiceException("修改用户失败");
         }

    }

    /**
     * 获取用户登录信息
     * @return 用户信息DTO
     */
    @Override
    public UserDTO getLoginUser() {
        // 1 获取当前登录的用户
        LoginUserDTO loginUserDTO = tokenService.getLoginUser();
        if(loginUserDTO==null){
            throw new ServiceException("用户令牌不合法" + ResultCode.INVALID_PARA.getCode());
        }
        // 2 远程调用获取用户信息
        R<AppUserVo> result = appUserFeignClient.findById(loginUserDTO.getUserId());
        if(result == null || result.getCode() != ResultCode.SUCCESS.getCode() || result.getData()==null){
            throw new ServiceException("用户查询失败" + ResultCode.INVALID_PARA.getCode());
        }
        // 3 对象拼装，返回结果
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(loginUserDTO,userDTO);
        BeanUtils.copyProperties(result.getData(),userDTO);
        return userDTO;
    }

    /**
     * 退出登录
     * @return void
     */
    @Override
    public void logout() {
        // 1 解析令牌
        String token = SecurityUtil.getToken();
        if (token == null) {
            throw new ServiceException("令牌不能为空" + ResultCode.INVALID_PARA.getCode());
        }
        // 2 打印删除用户信息
        String userName = JwtUtil.getUserName(token);
        String userId = JwtUtil.getUserId(token);
        log.info("{}退出了系统, 用户ID{}", userName, userId);
        // 3 删除用户缓存
        tokenService.delLoginUser(token);
    }

    /**
     * 发送短信验证码
     * @param phone 手机号
     * @return 验证码
     */
    @Override
    public String sendCode(String phone) {
        if (!VerifyUtil.checkPhone(phone)) {
            throw new ServiceException("手机号格式错误", ResultCode.INVALID_PARA.getCode());
        }
        return messageService.sendCode(phone);
    }



    /**
     * 处理微信登录逻辑
     * @param wechatLoginDTO 微信登录DTO
     * @param loginUserDTO 用户生命周期对象
     */
    private void loginByWechat(WechatLoginDTO wechatLoginDTO, LoginUserDTO loginUserDTO) {
        // 调用接口判断用户是否已存在
        AppUserVo appUserVo = null;
        R<AppUserVo> userVoR =  appUserFeignClient.findByOpenId(wechatLoginDTO.getOpenId());
        if(userVoR == null || userVoR.getData() == null || userVoR.getCode() != ResultCode.SUCCESS.getCode()){
            // 用户不存在则注册
            appUserVo = register(wechatLoginDTO);
        }else {
            // 拿取用户参数
            appUserVo = userVoR.getData();
        }
        // 设置登录信息：用户名称 和 用户id
        loginUserDTO.setUserName(appUserVo.getNickName());
        loginUserDTO.setUserId(appUserVo.getUserId());
    }

    /**
     * 根据入参来注册
     * @param loginDTO 用户生命周期信息
     * @return 用户VO
     */
    private AppUserVo register(LoginDTO loginDTO) {
        // 走哪个 if 都要创建的
        R<AppUserVo> result = null;
        if(loginDTO instanceof WechatLoginDTO wechatLoginDTO){
            result = appUserFeignClient.registerByOpenId(wechatLoginDTO.getOpenId());
            if(result == null || result.getCode() != ResultCode.SUCCESS.getCode() || result.getData() == null){
                log.error("用户注册失败! {}", wechatLoginDTO.getOpenId());
            }
        }else if(loginDTO instanceof CodeLoginDTO codeLoginDTO){
            result = appUserFeignClient.registerByPhone(codeLoginDTO.getPhone());
            if(result == null || result.getCode() != ResultCode.SUCCESS.getCode() || result.getData() == null){
                log.error("用户注册失败! {}", codeLoginDTO.getPhone());
            }
        }
        return result.getData() == null ? null : result.getData();
    }



}
